public with sharing class EnhancedLookupController  {
    
        public String displayColumn         { get; set; }
        public String objectToLookup        { get; set; }
        public String siteUrl               { get; set; }
        public String host              { get; set; }
        public String extension             { get; set; }

        public String displayName           { get; set; }
        public String filterString          { get; set; }
        public transient List<JsonObject> jsonObjs { get; set; }        
        public Boolean bigset               { get; set; }
        public List<String> paramValues     { get; set; }
        public List<String> paramKeys       { get; set; }
        public Map<String,String> params    { get; set; }
        public String secondDisplayColumn   { get; set; }
        public String thirdDisplayColumn    { get; set; }  
        public String alternateIdColumn    { get; set; } 
        private transient String jsonData;  
        
        
    public enhancedLookupController()  
    {
        System.debug('before: '+filterString);
            host = ApexPages.currentPage().getHeaders().get('Host');
        System.debug('after: '+filterString);
        
         
    }

     /** invoked on an Ajax request */    
    public void doSearch() {
        
          params = ApexPages.currentPage().getParameters();
          paramValues = params.values();
          paramKeys = new List <String>();
          paramKeys.addAll(params.keySet());
          
          
          for(String s: paramKeys)  
              System.debug('k:' + s);
          for(String s: paramValues)
              System.debug('v:' + s);
                
        if(params.get('otl') != null)
            objectToLookup = params.get('otl');
        else if (objectToLookup == null)
            objectToLookup = 'Account';
            
        if(params.get('dc') != null)
            displayColumn = params.get('dc');
        else if (displayColumn == null)
            displayColumn = 'name';         
  
        if(params.get('filterstring') != null)
            filterString = params.get('filterstring');
        else if (filterString == null)  
            filterString = '';
            
        if(params.get('sdc') != null)
            secondDisplayColumn = params.get('sdc');
        else if (secondDisplayColumn == null)  
            secondDisplayColumn = '';  
            
        if(params.get('aidc') != null)
            alternateIdColumn = params.get('aidc');
        else if (alternateIdColumn == null)  
            alternateIdColumn = '';  
    
        
                
        List<Sobject> records;

        String term = params.get('term');

        
        if(term != null)
            records = getRecords(term);    
          
        if (records != null && !records.isEmpty()) {  
            // Jsonify the results !
            jsonObjs = new List<JSONObject>();   
            for (Sobject o : records) {
                JSONObject cjson = new JSONObject();
                cjson.putOpt('id', new JSONObject.value((String) o.get('id')));
                if(secondDisplayColumn != null)  {

                    if(thirdDisplayColumn != null)  {

                        cjson.putOpt('label', new JSONObject.value((String) o.get(displayColumn) + '(' + ( (String) o.get(secondDisplayColumn) ) + ',' + ( (String) o.get(thirdDisplayColumn) ) + ')' ));
                    }
                    else
                        cjson.putOpt('label', new JSONObject.value((String) o.get(displayColumn) + '(' + ( (String) o.get(secondDisplayColumn) ) + ')' ));
                        
                }          
                else
                    cjson.putOpt('label', new JSONObject.value((String) o.get(displayColumn)));
                    
                cjson.putOpt('value', new JSONObject.value((String) o.get(displayColumn)));
                cjson.putOpt('aidc', new JSONObject.value((String) o.get(alternateIdColumn)));
                cjson.putOpt('name', new JSONObject.value((String) o.get('name')));
                jsonObjs.add(cjson);  

            }   

        }
    }
    
    // Does the SOQL query, using Ajax request data
    public List<SObject> getRecords(String filter) {
        System.debug('WeGotIt' + filter.length());
        List<SObject> records = new List<SObject>();
        //todo: get it from param
        String limitString = 'limit 20';  

        if (filter != null && filter.trim().length() > 0){
            String completeFilter; 
   if(filter.length() > 3)
               completeFilter =  '%' + String.escapeSingleQuotes(filter)  + '%';
            else
               completeFilter =  String.escapeSingleQuotes(filter)  + '%';   
                             
            if(filterString.trim().startsWith('WHERE'))
                filterString = 'AND' + filterString.trim().substring(5, filterString.length());
             filterString += ' order by ' + displayColumn + ' ' ;    
            String queryString = 'select id, ' + displayColumn;
            if(secondDisplayColumn != null) {
                queryString += ', ' + secondDisplayColumn;
                if(thirdDisplayColumn != null)
                    queryString += ', ' + thirdDisplayColumn;
            }
            queryString += ' from ' + objectToLookup + ' where ' + displayColumn + ' like \'' + completeFilter + '\' ';
            
           
            
            if(filterString.toLowerCase().contains('limit'))
                queryString += filterString;
            else
                queryString += filterString + ' ' + limitString;
            
            
            
            System.debug('QUERYSTRING: ' + queryString);
            
            records = Database.query(queryString);
            
        }     
        else {

            String queryString = 'select id, ' + displayColumn;
            if(secondDisplayColumn != null) {
                queryString += ', ' + secondDisplayColumn;
                if(thirdDisplayColumn != null)
                    queryString += ', ' + thirdDisplayColumn;
            }
            queryString += ' from ' + objectToLookup + ' ';
            
            if(filterString.toLowerCase().contains('limit'))
                queryString += filterString;
            else
                queryString += filterString + ' ' + limitString;


            System.debug('QUERYSTRING: ' + queryString);
            records = Database.query(queryString);
                        
        }  
        return records;      
    }    

    // Returns the JSON result string
    public String getResult() {
        if(jsonObjs != null)
            return JsonUtils.jsonify(jsonObjs);
        else return '[ ]';        
    }

    

}